﻿using System;
using System.Collections.Generic;

using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Library
{
    public class Water : Component
    {
        private Effect waterEffect;
        private Texture2D[] waterNormalMaps;

        private VertexPositionNormalTexture[] WaterVerts;
        private VertexDeclaration WaterVD;
        private TextureCube skyTexture;

        public Water(Effect effect, TextureCube sky)
        {

            this.DrawOrder = 0;
            waterEffect = effect;
            skyTexture = sky;

            waterNormalMaps = new Texture2D[5];
            for (int i = 0; i < 5; i++)
                waterNormalMaps[i] = Engine.Content.Load<Texture2D>("Content/Textures/Ocean" + (i + 1) + "_N");
            SetupWaterVertices();
        }

        void SetupWaterVertices()
        {
            WaterVerts = new VertexPositionNormalTexture[6];
            WaterVerts[0] = new VertexPositionNormalTexture(new Vector3(-1000, 0.2f, -1000), Vector3.Up, new Vector2(0, 0));
            WaterVerts[1] = new VertexPositionNormalTexture(new Vector3(1000, 0.2f, -1000), Vector3.Up, new Vector2(1, 0));
            WaterVerts[2] = new VertexPositionNormalTexture(new Vector3(-1000, 0.2f, 1000), Vector3.Up, new Vector2(0, 1));
            WaterVerts[3] = WaterVerts[2];
            WaterVerts[4] = WaterVerts[1];
            WaterVerts[5] = new VertexPositionNormalTexture(new Vector3(1000, 0.2f, 1000), Vector3.Up, new Vector2(1, 1));
            WaterVD = new VertexDeclaration(Engine.GraphicsDevice, VertexPositionNormalTexture.VertexElements);
        }

        public override void Draw()
        {
            waterEffect.Begin();
            waterEffect.CurrentTechnique.Passes[0].Begin();

            // set the transforms
            waterEffect.Parameters["World"].SetValue(Matrix.Identity);
            waterEffect.Parameters["View"].SetValue(Engine.Services.GetService<Camera>().View);
            waterEffect.Parameters["Projection"].SetValue(Engine.Services.GetService<Camera>().Projection);
            waterEffect.Parameters["EyePos"].SetValue(Engine.Services.GetService<Camera>().Position);

            // choose and set the ocean textures
            int waterTexIndex = ((int)(Engine.GameTime.TotalGameTime.TotalSeconds) % 5);
            waterEffect.Parameters["normalTex"].SetValue(waterNormalMaps[(waterTexIndex + 1) % 5]);
            waterEffect.Parameters["normalTex2"].SetValue(waterNormalMaps[(waterTexIndex) % 5]);
            waterEffect.Parameters["textureLerp"].SetValue((((((float)Engine.GameTime.TotalGameTime.TotalSeconds) - (int)(Engine.GameTime.TotalGameTime.TotalSeconds)) * 2 - 1) * 0.5f) + 0.5f);

            // set the time used for moving waves
            waterEffect.Parameters["time"].SetValue((float)Engine.GameTime.TotalGameTime.TotalSeconds * 0.02f);

            // set the sky texture
            waterEffect.Parameters["cubeTex"].SetValue(skyTexture);

            waterEffect.CommitChanges();

            // draw our geometry
            Engine.GraphicsDevice.VertexDeclaration = WaterVD;
            Engine.GraphicsDevice.DrawUserPrimitives<VertexPositionNormalTexture>(PrimitiveType.TriangleList, WaterVerts, 0, 2);
            Engine.GraphicsDevice.RenderState.CullMode = CullMode.None;
            // and we're done!
            waterEffect.CurrentTechnique.Passes[0].End();
            waterEffect.End();
        }
    }
}
